#include "imghelper.h"
#include "QSharedPointer"
#include "iostream"
#include "QMessageBox"
#include "QApplication"
#include "utils/random.h"

using namespace std;

Q_GLOBAL_STATIC(ImgHelper,instance)

ImgHelper::ImgHelper(QObject *parent): QObject(parent)
{

}

ImgHelper::~ImgHelper()
{
}

ImgHelper *ImgHelper::getInstance()
{
    return instance;
}

QImage ImgHelper::getGameWindowsScreenshots(QRectF rect)
{

    if(rect.isEmpty()){
        rect = GameManager::getInstantce()->gameRect;
    }
    QScreen *screen = QGuiApplication::primaryScreen();
    QImage qImage;
    if(screen == nullptr || !screen->size().isValid()) return qImage;
    QPixmap map = screen->grabWindow(0, rect.left(), rect.top(), rect.width() , rect.height());
    qImage = map.toImage();
    return  qImage;
}

//将QImage转化为Mat
Mat ImgHelper::qImageToCvMat( const QImage &inImage, bool inCloneImageData)
{
    switch ( inImage.format() )
    {
    // 8-bit, 4 channel
    case QImage::Format_ARGB32:
    case QImage::Format_ARGB32_Premultiplied:
    {
        Mat  mat( inImage.height(), inImage.width(),CV_8UC4,const_cast<uchar*>(inImage.bits()), static_cast<size_t>(inImage.bytesPerLine()));

        return (inCloneImageData ? mat.clone() : mat);
    }

        // 8-bit, 3 channel
    case QImage::Format_RGB32:
    case QImage::Format_RGB888:
    {
        if ( !inCloneImageData )
        {
            qWarning() << "CVS::QImageToCvMat() - Conversion requires cloning because we use a temporary QImage";
        }

        QImage   swapped = inImage;

        if ( inImage.format() == QImage::Format_RGB32 )
        {
            swapped = swapped.convertToFormat( QImage::Format_RGB888 );
        }

        swapped = swapped.rgbSwapped();

        return Mat( swapped.height(), swapped.width(),CV_8UC3,const_cast<uchar*>(swapped.bits()),static_cast<size_t>(swapped.bytesPerLine())).clone();
    }

        // 8-bit, 1 channel
    case QImage::Format_Indexed8:
    {
        Mat  mat( inImage.height(), inImage.width(),CV_8UC1,const_cast<uchar*>(inImage.bits()),static_cast<size_t>(inImage.bytesPerLine()));

        return (inCloneImageData ? mat.clone() : mat);
    }

    default:
        qWarning() << "CVS::QImageToCvMat() - QImage format not handled in switch:" << inImage.format();
        break;
    }

    return Mat();
}

QRect ImgHelper::getRotatedRect(Scalar startScalar, Scalar endtScalar, QRect rect)
{
    QImage gameImg = getGameWindowsScreenshots();
    QRect gameRect = GameManager::getInstantce()->gameRect;
    QRect cutRect = QRect(gameRect.left() + rect.left(), gameRect.top() + rect.top(), rect.width(), rect.height());
    QImage cutImg = gameImg.copy(cutRect);
    Mat mainImg = qImageToCvMat(cutImg, true);
    Mat grayImage;
    cvtColor(mainImg, grayImage, COLOR_BGR2HSV);
    Mat binMat, detImg, con;
    inRange(grayImage,startScalar, endtScalar,binMat);
    Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
    morphologyEx(binMat, detImg, MORPH_CLOSE,kernel);
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(detImg, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
    Rect re;
    for (unsigned int i = 0; i < contours.size(); i++) {
        re = boundingRect(contours[i]);
    }
    return QRect(re.x, re.y, re.width, re.height);
}


bool ImgHelper::getGameMatchPoint(QString templPath, QRectF *rect)
{
    QImage templ(templPath);
    if(templ.size().width() == 0){
        qDebug()<< "未找到模板图片" << templPath;
        return false;
    }
    //将主图转化成灰度图，zai再转成黑白二值图
    QImage qPixmap = ImgHelper::getGameWindowsScreenshots();

    if(qPixmap.size().width() <= 0 ||qPixmap.size().height() <=0 ){
        qDebug()<< "qPixmap==" << "为获取到屏幕截图，HANDLE可能为空";
        return false;
    }

    Mat mainMat = ImgHelper::qImageToCvMat(qPixmap);
    Mat gray_image;
    Mat binMainImg;
    cvtColor(mainMat, gray_image,COLOR_BGR2GRAY);
    threshold(gray_image, binMainImg, 70, 255, THRESH_BINARY);

    //将模板图转化成灰度图，zai再转成黑白二值图
    Mat templMat = ImgHelper::qImageToCvMat(templ, true);
    Mat grayTempl;
    Mat binTempl;
    cvtColor(templMat, grayTempl,COLOR_BGR2GRAY);
    threshold(grayTempl, binTempl, 70, 255, THRESH_BINARY);

    Mat resultMat;
    int result_cols = binMainImg.cols - binMainImg.cols + 1;
    int result_rows = binMainImg.rows - binMainImg.rows + 1;
    resultMat.create(result_cols, result_rows, CV_8UC1);
    matchTemplate(binMainImg, binTempl, resultMat, TM_SQDIFF_NORMED);//这里我们使用的匹配算法是标准平方差匹配 method=CV_TM_SQDIFF_NORMED，数值越小匹配度越好

    normalize(resultMat, resultMat, 0, 1, NORM_MINMAX, -1, Mat());
    double minVal = -1;
    double maxVal;
    Point minLoc;
    Point maxLoc;
    Point matchLoc;
    minMaxLoc(resultMat, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

    matchLoc = minLoc;
    if(minVal ==0 ||  maxVal == 0){
        qDebug() << "未匹配到合适坐标" << templPath;
        return false;
    }
    rectangle(binMainImg, matchLoc, Point(matchLoc.x + grayTempl.cols, matchLoc.y + grayTempl.rows), Scalar(255,255, 255), 2, 4, 0);

    if(rect != nullptr){
        rect->setLeft(matchLoc.x + GAME_WINDOWS_X + Random::getInstance()->getIntRandom(6) - 3);
        rect->setTop(matchLoc.y +GAME_WINDOWS_Y + Random::getInstance()->getIntRandom(6) - 3);
        rect->setRight(matchLoc.x + grayTempl.cols+ Random::getInstance()->getIntRandom(6) - 3);
        rect->setBottom(matchLoc.y + grayTempl.rows+ Random::getInstance()->getIntRandom(6) - 3);
    }

    return true;

}

bool ImgHelper:: getGameMatchMultiPoint(QString templPath,Scalar startScalar,Scalar endtScalar,float threshold, QList<QSharedPointer<QRectF>> *listfloat,QRectF percentRect)
{
    QImage templ(templPath);
    if(templ.size().width() == 0){
        qDebug()<< "未找到模板图片";
        return false;
    }
    //将主图转化成灰度图，zai再转成黑白二值图
    QImage qPixmap = ImgHelper::getGameWindowsScreenshots();

    if(qPixmap.isNull()){
        qDebug()<< "qPixmap==" << "未获取到屏幕截图，HANDLE可能为空";
        return false;
    }

    Mat mainMat = ImgHelper::qImageToCvMat(qPixmap, true);
    Mat gray_image;
    Mat hsvMainImg;
    cvtColor(mainMat, gray_image,COLOR_BGR2HSV);
    inRange(gray_image, startScalar, endtScalar, hsvMainImg);

    //将模板图转化成灰度图，zai再转成黑白二值图
    Mat templMat = ImgHelper::qImageToCvMat(templ, true);
    Mat grayTempl;
    Mat hsvTemplMat;
    cvtColor(templMat, grayTempl,COLOR_BGR2HSV);
    inRange(grayTempl, startScalar, endtScalar, hsvTemplMat);

    Mat resultMat;
    int result_cols = hsvMainImg.cols - hsvMainImg.cols + 1;
    int result_rows = hsvMainImg.rows - hsvMainImg.rows + 1;
    resultMat.create(result_cols, result_rows, CV_8UC1);
    matchTemplate(hsvMainImg, hsvTemplMat, resultMat, TM_CCORR_NORMED);//这里我们使用的匹配算法是标准平方差匹配 method=CV_TM_SQDIFF_NORMED，数值越小匹配度越好

    for(int y = resultMat.rows *1.0f * percentRect.y(); y < resultMat.rows *1.0f * percentRect.height(); y++){
        bool flag = false;
        for(int x = resultMat.cols *1.0f * percentRect.x(); x < resultMat.cols  *1.0f * percentRect.width(); x++ ){
            float f = resultMat.at<float>(y, x);

            if(f >= threshold){
                QSharedPointer<QRectF> obj = QSharedPointer<QRectF>(new QRectF());
                obj->setLeft(x + GAME_WINDOWS_X + Random::getInstance()->getIntRandom(6) - 3);
                obj->setTop(y +GAME_WINDOWS_Y + Random::getInstance()->getIntRandom(6) - 3);
                obj->setRight(x + grayTempl.cols+ Random::getInstance()->getIntRandom(6) - 3);
                obj->setBottom(y + grayTempl.rows+ Random::getInstance()->getIntRandom(6) - 3);
                listfloat->append(obj);
//                rectangle(mainMat, Point(x,y), Point(x + hsvTemplMat.cols, y + hsvTemplMat.rows), Scalar(255, 0, 255),2,16);

                x += hsvTemplMat.cols / 3;
                flag = true;
            }
        }
        if(flag){
            y += hsvTemplMat.rows / 3;
            flag = false;
        }

    }

    qDebug() << templPath << "threshold" << threshold << listfloat->size();
    return !listfloat->isEmpty();

}

bool ImgHelper::getGameMatchPoint(QString templPath, Scalar startScalar, Scalar endtScalar, QRectF percentRect, QRectF *outRect)
{
    QImage templ(templPath);
    if(templ.isNull()){
        qDebug()<< "qPixmap==" << "未找到模板图片";
        return false;
    }
    //将主图转化成灰度图，zai再转成黑白二值图
    QImage qImg = ImgHelper::getGameWindowsScreenshots();

    int left = qImg.width() * percentRect.x();
    int top = qImg.height() * percentRect.y();
    int width = qImg.width() * percentRect.width() - left; //新矩形的宽度
    int height = qImg.height() * percentRect.height() - top; //新矩形的高度

    QImage qPixmap = qImg.copy(left, top, width, height);

    if(qPixmap.isNull() || qPixmap.size().width() <= 0 ||qPixmap.size().height() <=0 ){
        return false;
    }


    if(qPixmap.size().width() <= 0 ||qPixmap.size().height() <=0 ){
        qDebug()<< "qPixmap==" << "为获取到屏幕截图，HANDLE可能为空";
        return false;
    }

    Mat mainMat = ImgHelper::qImageToCvMat(qPixmap);
    Mat gray_image;
    Mat hsvMainImg;
    cvtColor(mainMat, gray_image,COLOR_BGR2HSV);
    inRange(gray_image, startScalar, endtScalar, hsvMainImg);

    //将模板图转化成灰度图，zai再转成黑白二值图
    Mat templMat = ImgHelper::qImageToCvMat(templ, true);
    Mat grayTempl;
    Mat hsvTemplMat;
    cvtColor(templMat, grayTempl,COLOR_BGR2HSV);
    inRange(grayTempl, startScalar, endtScalar, hsvTemplMat);

    Mat resultMat;
    int result_cols = hsvMainImg.cols - hsvMainImg.cols + 1;
    int result_rows = hsvMainImg.rows - hsvMainImg.rows + 1;
    resultMat.create(result_cols, result_rows, CV_8UC1);
    matchTemplate(hsvMainImg, hsvTemplMat, resultMat, TM_CCOEFF_NORMED);//这里我们使用的匹配算法是标准平方差匹配 method=CV_TM_SQDIFF_NORMED，数值越小匹配度越好

    double minVal = -1;
    double maxVal;
    Point minLoc;
    Point maxLoc;
    Point matchLoc;
    minMaxLoc(resultMat, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

    matchLoc = maxLoc;
    if(minVal ==0 ||  maxVal == 0){
        return false;
    }
    rectangle(hsvTemplMat, matchLoc, Point(matchLoc.x + grayTempl.cols, matchLoc.y + grayTempl.rows), Scalar(255,255, 255), 2, 4, 0);

    if(outRect != nullptr){
        outRect->setLeft(matchLoc.x + GAME_WINDOWS_X + Random::getInstance()->getIntRandom(6) - 3);
        outRect->setTop(matchLoc.y +GAME_WINDOWS_Y  + Random::getInstance()->getIntRandom(6) - 3);
        outRect->setRight(matchLoc.x + grayTempl.cols + Random::getInstance()->getIntRandom(6) - 3);
        outRect->setBottom(matchLoc.y + grayTempl.rows + Random::getInstance()->getIntRandom(6) - 3);
    }

    return true;
}


bool ImgHelper::getGameMatchPoint(QString templPath, Scalar startScalar, Scalar endtScalar,float threshold, QRectF percentRect, QRectF *outRect)
{
    QImage templ(templPath);
    if(templ.isNull()){
        qDebug()<< "qPixmap==" << "未找到模板图片";
        return false;
    }
    //将主图转化成灰度图，zai再转成黑白二值图
    QImage qImg = ImgHelper::getGameWindowsScreenshots();

    int left = qImg.width() * percentRect.x();
    int top = qImg.height() * percentRect.y();
    int width = qImg.width() * percentRect.width() - left; //新矩形的宽度
    int height = qImg.height() * percentRect.height() - top; //新矩形的高度

    QImage qPixmap = qImg.copy(left, top, width, height);

    if(qPixmap.isNull() || qPixmap.size().width() <= 0 ||qPixmap.size().height() <=0 ){
        return false;
    }

    Mat mainMat = ImgHelper::qImageToCvMat(qPixmap);
//    Mat mainMat = imread("C:/Users/ALEX/Desktop/game/zdxl.png");
    Mat gray_image;
    Mat hsvMainImg;
    cvtColor(mainMat, gray_image,COLOR_BGR2HSV);
    inRange(gray_image, startScalar, endtScalar, hsvMainImg);
    //将模板图转化成灰度图，zai再转成黑白二值图
    Mat templMat = ImgHelper::qImageToCvMat(templ, true);
    Mat grayTempl;
    Mat hsvTemplMat;
    cvtColor(templMat, grayTempl,COLOR_BGR2HSV);
    inRange(grayTempl, startScalar, endtScalar, hsvTemplMat);


    Mat resultMat;
    int result_cols = hsvMainImg.cols - hsvMainImg.cols + 1;
    int result_rows = hsvMainImg.rows - hsvMainImg.rows + 1;
    resultMat.create(result_cols, result_rows, CV_8UC1);
    matchTemplate(hsvMainImg, hsvTemplMat, resultMat, TM_CCOEFF_NORMED);//这里我们使用的匹配算法是标准平方差匹配 method=CV_TM_SQDIFF_NORMED，数值越小匹配度越好

    double minVal = -1;
    double maxVal;
    Point minLoc;
    Point maxLoc;
    Point matchLoc;
    minMaxLoc(resultMat, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

    matchLoc = maxLoc;
    if(maxVal < threshold){
         qDebug() << "未匹配到合适坐标" << "maxVal=" << maxVal << "threshold=" << threshold << templPath;
        return false;
    }
    qDebug() << "配到合适坐标" <<"x=" << matchLoc.x<< "y=" << matchLoc.y << "maxVal" << maxVal << templPath;
    rectangle(mainMat, matchLoc, Point(matchLoc.x + grayTempl.cols, matchLoc.y + grayTempl.rows), Scalar(255,255, 255), 2, 4, 0);

    if(outRect != nullptr){
        outRect->setLeft(matchLoc.x + GAME_WINDOWS_X + left + Random::getInstance()->getIntRandom(6) - 3);
        outRect->setTop(matchLoc.y +GAME_WINDOWS_Y + top+ Random::getInstance()->getIntRandom(6) - 3);
        outRect->setRight(matchLoc.x + grayTempl.cols + left+ Random::getInstance()->getIntRandom(6) - 3);
        outRect->setBottom(matchLoc.y + grayTempl.rows + top+ Random::getInstance()->getIntRandom(6) - 3);
    }
    return true;
}

bool ImgHelper::getGameMatchPointAsb(QString templPath, Scalar startScalar, Scalar endtScalar,float threshold, QRectF rect, QRectF *outRect)
{
    QImage templ(templPath);
    if(templ.isNull()){
        qDebug()<< "qPixmap==" << "未找到模板图片";
        return false;
    }

    QImage qPixmap =  ImgHelper::getGameWindowsScreenshots(rect);

    if(qPixmap.isNull() || qPixmap.size().width() <= 0 ||qPixmap.size().height() <=0 ){
        return false;
    }

    Mat mainMat = ImgHelper::qImageToCvMat(qPixmap);
//    Mat mainMat = imread("C:/Users/ALEX/Desktop/game/zdxl.png");
    Mat gray_image;
    Mat hsvMainImg;
    cvtColor(mainMat, gray_image,COLOR_BGR2HSV);
    inRange(gray_image, startScalar, endtScalar, hsvMainImg);
    //将模板图转化成灰度图，zai再转成黑白二值图
    Mat templMat = ImgHelper::qImageToCvMat(templ, true);
    Mat grayTempl;
    Mat hsvTemplMat;
    cvtColor(templMat, grayTempl,COLOR_BGR2HSV);
    inRange(grayTempl, startScalar, endtScalar, hsvTemplMat);

    Mat resultMat;
    int result_cols = hsvMainImg.cols - hsvMainImg.cols + 1;
    int result_rows = hsvMainImg.rows - hsvMainImg.rows + 1;
    resultMat.create(result_cols, result_rows, CV_8UC1);
    matchTemplate(hsvMainImg, hsvTemplMat, resultMat, TM_CCOEFF_NORMED);//这里我们使用的匹配算法是标准平方差匹配 method=CV_TM_SQDIFF_NORMED，数值越小匹配度越好

    double minVal = -1;
    double maxVal;
    Point minLoc;
    Point maxLoc;
    Point matchLoc;
    minMaxLoc(resultMat, &minVal, &maxVal, &minLoc, &maxLoc, Mat());

    matchLoc = maxLoc;
    if(maxVal < threshold){
         qDebug() << "未匹配到合适坐标" << "maxVal=" << maxVal << "threshold=" << threshold << templPath;
        return false;
    }
    qDebug() << "配到合适坐标" <<"x=" << matchLoc.x<< "y=" << matchLoc.y << "maxVal" << maxVal << templPath;
    rectangle(mainMat, matchLoc, Point(matchLoc.x + grayTempl.cols, matchLoc.y + grayTempl.rows), Scalar(255,255, 255), 2, 4, 0);

    if(outRect != nullptr){
        outRect->setLeft(matchLoc.x + GAME_WINDOWS_X + rect.left() + Random::getInstance()->getIntRandom(6) - 3);
        outRect->setTop(matchLoc.y +GAME_WINDOWS_Y + rect.top()+ Random::getInstance()->getIntRandom(6) - 3);
        outRect->setRight(matchLoc.x + grayTempl.cols + rect.left()+ Random::getInstance()->getIntRandom(6) - 3);
        outRect->setBottom(matchLoc.y + grayTempl.rows + rect.top()+ Random::getInstance()->getIntRandom(6) - 3);
    }
    return true;
}

bool ImgHelper::getTextByImg(Scalar startScalar, Scalar endtScalar, QRectF percentRect, StringBoxBean &strsInfo,PageIteratorLevel level)
{
    //将主图转化成灰度图，zai再转成黑白二值图
    QImage qImg = ImgHelper::getGameWindowsScreenshots();

    int left = qImg.width() * percentRect.x();
    int top = qImg.height() * percentRect.y();
    int width = qImg.width() * percentRect.width() - left; //新矩形的宽度
    int height = qImg.height() * percentRect.height() - top; //新矩形的高度

    QImage qPixmap = qImg.copy(left, top, width, height);

    if(qPixmap.isNull() || qPixmap.size().width() <= 0 ||qPixmap.size().height() <=0 ){
        return false;
    }

    Mat mainMat = ImgHelper::qImageToCvMat(qPixmap);
    Mat gray_image;
    Mat hsvMainImg;
    cvtColor(mainMat, gray_image,COLOR_BGR2HSV);
    inRange(gray_image, startScalar, endtScalar, hsvMainImg);
    getTextByMat(hsvMainImg,strsInfo,level);
    return true;
}

void ImgHelper::getTextByMat(Mat mat, StringBoxBean &strsInfo,PageIteratorLevel level)
{
//    tesseract::RIL_WORD
    TessBaseAPI api;
     QString path = QApplication::applicationDirPath() + "/tessdata";
    api.Init(path.toLocal8Bit(), "normal88", tesseract::OEM_DEFAULT);
    api.SetImage(mat.data, mat.cols, mat.rows, mat.channels(), mat.step1());
     Boxa* boxes = api.GetComponentImages(level, true, NULL, NULL);//获得文本框坐标信息
     if(boxes == nullptr) return;
     for (int i = 0; i < boxes->n; i++) {//将文本框逐个识别
         BOX* box = boxaGetBox(boxes, i, L_CLONE);
         api.SetRectangle(box->x, box->y, box->w, box->h);//将第i个文本框设置为识别区域，即只识别这一个小区域
         char* ocrResult = api.GetUTF8Text();//获得识别结果
         int conf = api.MeanTextConf();//获得置信度
//         fprintf(stdout, "Box[%d]: x=%d, y=%d, w=%d, h=%d, confidence: %d, text: %s",
//                         i, box->x, box->y, box->w, box->h, conf, ocrResult);//输出坐标框的信息
//         qDebug() << "i=" << i << "x=" << box->x << "y=" << box->y << "conf=" << conf << "ocrResult=" << ocrResult;

         strsInfo.word =QString(ocrResult);
         strsInfo.x = box->x;
         strsInfo.y = box->y;

         boxDestroy(&box);//销毁相关结构体
     }
    api.Clear();
    api.End();
}

bool ImgHelper::getNumByImgAbs(Scalar startScalar, Scalar endtScalar, QRectF asbRect, StringBoxBean &strsInfo,PageIteratorLevel level)
{
    //将主图转化成灰度图，zai再转成黑白二值图
    QImage qPixmap = ImgHelper::getGameWindowsScreenshots(asbRect);

    if(qPixmap.isNull() || qPixmap.size().width() <= 0 ||qPixmap.size().height() <=0 ){
        return false;
    }

    Mat mainMat = ImgHelper::qImageToCvMat(qPixmap);
    Mat gray_image;
    Mat hsvMainImg;
    cvtColor(mainMat, gray_image,COLOR_BGR2HSV);
    inRange(gray_image, startScalar, endtScalar, hsvMainImg);
    getNumByMat(hsvMainImg,strsInfo,level);
    return true;
}

bool ImgHelper::getNumByImg(Scalar startScalar, Scalar endtScalar, QRectF percentRect, StringBoxBean &strsInfo,PageIteratorLevel level)
{
    //将主图转化成灰度图，zai再转成黑白二值图
    QImage qImg = ImgHelper::getGameWindowsScreenshots();

    int left = qImg.width() * percentRect.x();
    int top = qImg.height() * percentRect.y();
    int width = qImg.width() * percentRect.width() - left; //新矩形的宽度
    int height = qImg.height() * percentRect.height() - top; //新矩形的高度

    QImage qPixmap = qImg.copy(left, top, width, height);

    if(qPixmap.isNull() || qPixmap.size().width() <= 0 ||qPixmap.size().height() <=0 ){
        return false;
    }

    Mat mainMat = ImgHelper::qImageToCvMat(qPixmap);
    Mat gray_image;
    Mat hsvMainImg;
    cvtColor(mainMat, gray_image,COLOR_BGR2HSV);
    inRange(gray_image, startScalar, endtScalar, hsvMainImg);
    getNumByMat(hsvMainImg,strsInfo,level);
    return true;
}

void ImgHelper::getNumByMat(Mat mat, StringBoxBean &strsInfo,PageIteratorLevel level)
{
//    tesseract::RIL_WORD
    TessBaseAPI api;
    QString path = QApplication::applicationDirPath() + "/tessdata";
    if(api.Init(path.toLocal8Bit(), "num", tesseract::OEM_DEFAULT) == -1) return;
    api.SetImage(mat.data, mat.cols, mat.rows, mat.channels(), mat.step1());
     Boxa* boxes = api.GetComponentImages(level, true, NULL, NULL);//获得文本框坐标信息
     if(boxes == nullptr) return;
     for (int i = 0; i < boxes->n; i++) {//将文本框逐个识别
         BOX* box = boxaGetBox(boxes, i, L_CLONE);
         qDebug() << box->x << "," << box->y << "," <<  box->w << ","<<  box->h;
         api.SetRectangle(box->x, box->y, box->w, box->h);//将第i个文本框设置为识别区域，即只识别这一个小区域
         char* ocrResult = api.GetUTF8Text();//获得识别结果
         int conf = api.MeanTextConf();//获得置信度

         strsInfo.word =QString(ocrResult);
         strsInfo.x = box->x;
         strsInfo.y = box->y;

         boxDestroy(&box);//销毁相关结构体
     }
    api.Clear();
    api.End();
}
